﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MultiDAQ_Analysis.Util
{
    /// <summary>
    /// UDP采集卡数据解析器
    /// 支持标准版和高阶版的通道数据解析
    /// </summary>
    public class UdpDataParser
    {
        // 帧头标识
        private static readonly byte[] FRAME_HEADER_BASE = { 0x5A };
        // 帧尾标识
        private static readonly byte[] FRAME_TAIL = { 0x0D, 0x0A };

        public event Action<string> OnLogMessage;
        public event Action<string> OnErrorMessage;
        public event Action<int, byte[]> OnChannelDataReceived; // 通道号，数据

        /// <summary>
        /// 是否为高阶版本（高阶版本通道1固定为空，且有通道映射）
        /// </summary>
        public bool IsAdvancedVersion { get; set; } = true;

        /// <summary>
        /// 界面选中的通道列表（用于高阶版本的映射）
        /// </summary>
        public HashSet<int> SelectedUIChannels { get; set; } = new HashSet<int>();

        /// <summary>
        /// 解析UDP接收到的完整数据包
        /// </summary>
        /// <param name="rawData">原始UDP数据</param>
        /// <returns>解析结果</returns>
        public UdpParseResult ParseData(byte[] rawData)
        {
            var result = new UdpParseResult();

            try
            {
                if (rawData == null || rawData.Length < 4) // 至少需要一个通道帧头+帧尾
                {
                    OnErrorMessage?.Invoke("接收数据为空或长度不足");
                    result.IsSuccess = false;
                    return result;
                }

                OnLogMessage?.Invoke($"开始解析UDP数据，总长度：{rawData.Length}字节");

                // 验证帧尾
                if (!HasValidFrameTail(rawData))
                {
                    OnErrorMessage?.Invoke("数据帧尾验证失败");
                    result.IsSuccess = false;
                    return result;
                }

                // 解析各通道数据
                int parsePosition = 0;
                int dataEndPosition = rawData.Length - FRAME_TAIL.Length;

                while (parsePosition < dataEndPosition)
                {
                    var channelResult = ParseSingleChannel(rawData, parsePosition, dataEndPosition);

                    if (channelResult.IsSuccess)
                    {
                        result.ChannelDataMap[channelResult.PhysicalChannel] = channelResult.Data;
                        OnChannelDataReceived?.Invoke(channelResult.PhysicalChannel, channelResult.Data);

                        OnLogMessage?.Invoke($"物理通道{channelResult.PhysicalChannel}解析成功，数据长度：{channelResult.Data.Length}字节");
                        parsePosition = channelResult.NextPosition;
                    }
                    else
                    {
                        OnErrorMessage?.Invoke($"解析通道数据失败，位置：{parsePosition}");
                        break;
                    }
                }

                result.IsSuccess = true;
                result.TotalChannels = result.ChannelDataMap.Count;

                // 应用高阶版本的通道映射逻辑
                if (IsAdvancedVersion)
                {
                    result.MappedChannelData = ApplyAdvancedChannelMapping(result.ChannelDataMap);
                }

                OnLogMessage?.Invoke($"UDP数据解析完成，成功解析{result.TotalChannels}个通道");
            }
            catch (Exception ex)
            {
                OnErrorMessage?.Invoke($"解析数据时发生异常：{ex.Message}");
                result.IsSuccess = false;
            }

            return result;
        }

        /// <summary>
        /// 解析单个通道的数据
        /// </summary>
        private SingleChannelParseResult ParseSingleChannel(byte[] rawData, int startPosition, int maxPosition)
        {
            var result = new SingleChannelParseResult();

            try
            {
                // 检查是否有足够的数据读取帧头
                if (startPosition + 2 > maxPosition)
                {
                    result.IsSuccess = false;
                    return result;
                }

                // 验证帧头格式 0x5A + 通道号
                if (rawData[startPosition] != 0x5A)
                {
                    result.IsSuccess = false;
                    return result;
                }

                // 获取物理通道号
                int physicalChannel = rawData[startPosition + 1];
                if (physicalChannel < 1 || physicalChannel > 8)
                {
                    result.IsSuccess = false;
                    return result;
                }

                result.PhysicalChannel = physicalChannel;

                // 查找下一个通道的帧头或帧尾，确定当前通道数据的边界
                int dataStartPosition = startPosition + 2;
                int nextChannelPosition = FindNextChannelStart(rawData, dataStartPosition, maxPosition);

                // 提取通道数据
                int dataLength = nextChannelPosition - dataStartPosition;
                if (dataLength >= 0)
                {
                    result.Data = new byte[dataLength];
                    if (dataLength > 0)
                    {
                        Array.Copy(rawData, dataStartPosition, result.Data, 0, dataLength);
                    }
                }
                else
                {
                    result.Data = new byte[0];
                }

                result.NextPosition = nextChannelPosition;
                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                OnErrorMessage?.Invoke($"解析单通道数据异常：{ex.Message}");
                result.IsSuccess = false;
            }

            return result;
        }

        /// <summary>
        /// 查找下一个通道的起始位置
        /// </summary>
        private int FindNextChannelStart(byte[] rawData, int searchStart, int maxPosition)
        {
            for (int i = searchStart; i < maxPosition - 1; i++)
            {
                if (rawData[i] == 0x5A && rawData[i + 1] >= 1 && rawData[i + 1] <= 8)
                {
                    return i; // 找到下一个通道帧头
                }
            }
            return maxPosition; // 没找到下一个通道，说明当前通道数据到帧尾前结束
        }

        /// <summary>
        /// 验证帧尾是否正确
        /// </summary>
        private bool HasValidFrameTail(byte[] rawData)
        {
            if (rawData.Length < FRAME_TAIL.Length)
                return false;

            int tailStart = rawData.Length - FRAME_TAIL.Length;
            for (int i = 0; i < FRAME_TAIL.Length; i++)
            {
                if (rawData[tailStart + i] != FRAME_TAIL[i])
                    return false;
            }
            return true;
        }

        /// <summary>
        /// 应用高阶版本的通道映射逻辑
        /// </summary>
        private Dictionary<int, byte[]> ApplyAdvancedChannelMapping(Dictionary<int, byte[]> physicalChannelData)
        {
            var mappedData = new Dictionary<int, byte[]>();

            try
            {
                OnLogMessage?.Invoke("应用高阶版本通道映射逻辑");

                // 高阶版本：界面选中通道N对应物理通道N+1的数据
                foreach (int uiChannel in SelectedUIChannels)
                {
                    int physicalChannel = uiChannel + 1; // 映射关系：界面通道N → 物理通道N+1

                    if (physicalChannelData.ContainsKey(physicalChannel))
                    {
                        mappedData[uiChannel] = physicalChannelData[physicalChannel];
                        OnLogMessage?.Invoke($"通道映射：界面通道{uiChannel} ← 物理通道{physicalChannel}数据");
                    }
                    else
                    {
                        // 物理通道无数据时，映射为空数据
                        mappedData[uiChannel] = new byte[0];
                        OnLogMessage?.Invoke($"通道映射：界面通道{uiChannel} ← 物理通道{physicalChannel}无数据");
                    }
                }

                OnLogMessage?.Invoke($"高阶版本映射完成，映射{mappedData.Count}个界面通道");
            }
            catch (Exception ex)
            {
                OnErrorMessage?.Invoke($"应用通道映射异常：{ex.Message}");
            }

            return mappedData;
        }

        /// <summary>
        /// 获取指定界面通道的数据（高阶版本）
        /// </summary>
        /// <param name="parseResult">解析结果</param>
        /// <param name="uiChannel">界面通道号</param>
        /// <returns>通道数据，如果无数据返回空数组</returns>
        public byte[] GetUIChannelData(UdpParseResult parseResult, int uiChannel)
        {
            if (!IsAdvancedVersion)
            {
                // 标准版本直接返回对应物理通道数据
                return parseResult.ChannelDataMap.ContainsKey(uiChannel)
                    ? parseResult.ChannelDataMap[uiChannel]
                    : new byte[0];
            }
            else
            {
                // 高阶版本返回映射后的数据
                return parseResult.MappedChannelData.ContainsKey(uiChannel)
                    ? parseResult.MappedChannelData[uiChannel]
                    : new byte[0];
            }
        }

        /// <summary>
        /// 检查指定界面通道是否有数据
        /// </summary>
        public bool HasUIChannelData(UdpParseResult parseResult, int uiChannel)
        {
            byte[] data = GetUIChannelData(parseResult, uiChannel);
            return data != null && data.Length > 0;
        }

        /// <summary>
        /// 获取所有有数据的界面通道列表
        /// </summary>
        public List<int> GetActiveUIChannels(UdpParseResult parseResult)
        {
            var activeChannels = new List<int>();

            if (!IsAdvancedVersion)
            {
                // 标准版本
                foreach (var kvp in parseResult.ChannelDataMap)
                {
                    if (kvp.Value != null && kvp.Value.Length > 0)
                    {
                        activeChannels.Add(kvp.Key);
                    }
                }
            }
            else
            {
                // 高阶版本
                foreach (var kvp in parseResult.MappedChannelData)
                {
                    if (kvp.Value != null && kvp.Value.Length > 0)
                    {
                        activeChannels.Add(kvp.Key);
                    }
                }
            }

            return activeChannels.OrderBy(x => x).ToList();
        }

        /// <summary>
        /// 将字节数组转换为十六进制字符串（用于调试）
        /// </summary>
        public string BytesToHexString(byte[] bytes, int maxLength = 32)
        {
            if (bytes == null || bytes.Length == 0)
                return "无数据";

            int length = Math.Min(bytes.Length, maxLength);
            var sb = new StringBuilder();

            for (int i = 0; i < length; i++)
            {
                sb.AppendFormat("{0:X2}", bytes[i]);
                if (i < length - 1) sb.Append(" ");
            }

            if (bytes.Length > maxLength)
                sb.Append($"...(共{bytes.Length}字节)");

            return sb.ToString();
        }
    }

    /// <summary>
    /// UDP数据解析结果
    /// </summary>
    public class UdpParseResult
    {
        public bool IsSuccess { get; set; } = false;
        public int TotalChannels { get; set; } = 0;

        /// <summary>
        /// 物理通道数据映射 (物理通道号 → 数据)
        /// </summary>
        public Dictionary<int, byte[]> ChannelDataMap { get; set; } = new Dictionary<int, byte[]>();

        /// <summary>
        /// 界面通道数据映射 (界面通道号 → 数据) - 仅高阶版本使用
        /// </summary>
        public Dictionary<int, byte[]> MappedChannelData { get; set; } = new Dictionary<int, byte[]>();

        public DateTime ParseTime { get; set; } = DateTime.Now;
    }

    /// <summary>
    /// 单通道解析结果
    /// </summary>
    internal class SingleChannelParseResult
    {
        public bool IsSuccess { get; set; } = false;
        public int PhysicalChannel { get; set; } = 0;
        public byte[] Data { get; set; } = new byte[0];
        public int NextPosition { get; set; } = 0;
    }
}
